package com.study.cloud.apilog.request;

import com.alibaba.fastjson.JSONObject;
import com.study.cloud.apilog.GatewayApiLog;
import com.study.cloud.utils.MediaTypeUtil;
import com.study.cloud.utils.SplitStringUtil;
import org.springframework.http.MediaType;
import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

import java.util.List;

/**
 * @Date 2022/5/17
 * @Author Cliff
 * desc
 */
@Component
public class ComplexRequestBodyImpl extends AbstractRequestBody {

    private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();


    @Override
    public boolean isSupport(MediaType mediaType) {
        return mediaType != null
                && (MediaTypeUtil.isFormDataType(mediaType)
                || MediaTypeUtil.isWWWFormType(mediaType)
                || MediaTypeUtil.isApplicationJsonType(mediaType));
    }

    @Override
    public BodyWrapper getRequestBody(ServerWebExchange exchange, GatewayApiLog gatewayLog) {
        ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
        // 通过 BodyInserter 插入 body(支持修改body), 避免 request body 只能获取一次
        BodyInserter BodyInserter = BodyInserters.fromPublisher(
                serverRequest.bodyToMono(String.class)
                        .flatMap(body -> requestValue(exchange, gatewayLog, body)), String.class);
        return new BodyWrapper(BodyInserter, gatewayLog);
    }


    private Mono<String> requestValue(ServerWebExchange exchange, GatewayApiLog gatewayLog, String body) {
        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
        if (MediaTypeUtil.isFormDataType(mediaType)) {
            JSONObject str = SplitStringUtil.splitFormStr(body);
            gatewayLog.setRequestBody(str.toJSONString());
        } else if (MediaTypeUtil.isWWWFormType(mediaType)) {
            JSONObject str = SplitStringUtil.splitWWWFormStr(body);
            gatewayLog.setRequestBody(str.toJSONString());
        } else {
            gatewayLog.setRequestBody(body);
        }
        System.out.println("请求体:==" + body);
        return Mono.just(body);
    }


}
